package cn.wb.org.service.impl;

import cn.wb.base.enm.ShopStateEnum;
import cn.wb.base.query.BaseQuery;
import cn.wb.base.service.impl.BaseServiceImpl;
import cn.wb.base.util.*;
import cn.wb.org.domain.Employee;
import cn.wb.org.domain.Shop;
import cn.wb.org.domain.ShopAuditLog;
import cn.wb.org.dto.EmployeeDto;
import cn.wb.org.dto.ShopAuditDto;
import cn.wb.org.dto.ShopDto;
import cn.wb.org.mapper.EmployeeMapper;
import cn.wb.org.mapper.ShopAuditLogMapper;
import cn.wb.org.mapper.ShopMapper;
import cn.wb.org.service.IShopService;
import cn.wb.system.domain.Role;
import cn.wb.system.mapper.RoleMapper;
import cn.wb.user.domain.Logininfo;
import cn.wb.user.mapper.LogininfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author itsource
 * @since 2022-12-26
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private ShopAuditLogMapper logMapper;

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;
    /**
     * 店铺入住
     */
    @Override
    @Transactional
    public void settlement(ShopDto dto) {
        // 参数校验
        verify(dto);
        // 保存数据
        save(dto);
    }

    /**
     * 审核通过
     * @param dto
     */
    @Override
    public void auditPass(ShopAuditDto dto) {
        // 1.参数校验
        // 2.修改状态为已审核/审核通过/待激活
        Shop shop = new Shop();
        shop.setId(dto.getShopId());
        shop.setState(ShopStateEnum.AUDIT_PASS.getCode());
        shopMapper.update(shop);
        // 3.保存日志
        ShopAuditLog log = new ShopAuditLog();
        log.setShopId(dto.getShopId());
        log.setNote(dto.getNote());
        log.setAuditTime(new Date());
        //  我们还没有学登录 先写死一个审核人
        log.setAuditId(LoginContext.getLogininfo().getId());
        logMapper.add(log);
        // 1.创建复杂邮件对象
        SendEmailUtil.send("<h1>尊敬的vip，恭喜您入住成功，请及时点击下方链接，激活店铺：</h1> " +
                    "http://localhost:8081/#/registerAgain?shopId="+dto.getShopId(),"452627526@qq.com");
    }

    @Override
    public void activity(Long id) {
        Shop shop = new Shop();
        shop.setId(id);
        shop.setState(ShopStateEnum.ACTIVITY.getCode());
        shopMapper.update(shop);
    }


    private void save(ShopDto dto) {
        // 添加 数据
        // 添加 shop
        Shop shop = dto.getShop();
        super.add(shop);
        // 添加 emp
        Employee emp = new Employee();
        EmployeeDto admin = dto.getAdmin();
        BeanUtils.copyProperties(admin,emp);
        emp.setAge(0);
        emp.setState(1);
        // todo 给emp 设置默认密码
        String salt = StrUtils.getComplexRandomString(32);
        emp.setSalt(salt);
        emp.setPassword(MD5Utils.encrypByMd5(salt+"1"));
        emp.setShopId(shop.getId());
        // todo 同步 logininfo表数据
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(emp,logininfo);
        logininfo.setDisable(1);
        logininfo.setType(0);
        logininfoMapper.add(logininfo);
        // todo 更新emp的 logininfoid
        emp.setLogininfoId(logininfo.getId());
        employeeMapper.add(emp);

        // todo 默认给当前人添加店长角色 如果确定店长的id可以直接写死 因为 我这边用的是本地的数据
        //  和教师机的数据是不一致的 所以我这边去查询一下
        List<Role> roleList = roleMapper.findAll();
        Optional<Role> any = roleList.stream().filter(role -> "dz001".equals(role.getSn())).findAny();
        any.ifPresent(role->{
            roleMapper.addMiddle(emp.getId(), Collections.singletonList(role.getId()));
        });
        // 修改shop的adminId字段
        Shop updateShop = new Shop();
        updateShop.setId(shop.getId());
        updateShop.setAdminId(emp.getId());
        super.update(updateShop);
    }

    private void verify(ShopDto dto) {
        // 1.参数校验

        // 2.两次密码是否一致
        if (!dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())){
            throw new BusinessException("两次密码不一致！");
        }
        // 3. 百度AI审核
        if (!BaiduAuditUtils.TextCensor(dto.getName())){
            throw new BusinessException("店铺名称不合规！");
        }
        if (!BaiduAuditUtils.ImgCensor(dto.getLogo())){
            throw new BusinessException("店铺logo不合规！");
        }


        // 4.店铺是否重复
        String shopName = dto.getName();
        // 根据店铺名称 去查询数据库 如果存在数据 那么就是有 就抛异常
        Shop shopDb = shopMapper.findByName(shopName);
        if (null != shopDb){
            throw new BusinessException("店铺已经存在，滚去登录！");
        }
        // 5.管理员是否已经管理了店铺
        // 根据管理员名称去查询数据是否存在
        String empName = dto.getAdmin().getUsername();
        Employee employee = employeeMapper.findByName(empName);
        if (null != employee && null != employee.getShopId()){
            // 不为空 当前人 属于店铺
            shopDb =  shopMapper.findByAdminId(employee.getId());
            if (null != shopDb){
                throw new BusinessException("当前管理员已经在管理店铺，换个人！");
            }
        }
    }

    @Override
    public PageList<Shop> queryByPage(BaseQuery query) {
        PageList<Shop> shopPageList = super.queryByPage(query);
        if (null == shopPageList || CollectionUtils.isEmpty(shopPageList.getRows())){
            return new PageList<>(0,new ArrayList<>());
        }
        // 还要根据shopId 去查询 log

        // 1.将 shopPageList 集合 中的shopId 取出来装到一个集合里面
        List<Shop> rows = shopPageList.getRows();
        List<Long> shopIds = rows.stream().map(Shop::getId).collect(Collectors.toList());
        // 根据当前的shopIds 批量查询 当前shopids对应的所有的 log集合
       List<ShopAuditLog> logs =  logMapper.findByShopIds(shopIds);
       // 将logs 根据shopId进行分组
        Map<Long, List<ShopAuditLog>> logMap = logs.stream().collect(Collectors.groupingBy(ShopAuditLog::getShopId));
        // 遍历 rows
        rows.forEach(shop->{
            List<ShopAuditLog> auditLogs = logMap.get(shop.getId());
            if (CollectionUtils.isEmpty(auditLogs)){
                auditLogs = new ArrayList<>();
            }
            shop.setAuditLogs(auditLogs);
        });

//        Map<Long, List<ShopAuditLog>> logMap = new HashMap<>();
//        for (ShopAuditLog log : logs) {
//            List<ShopAuditLog> auditLogs = logMap.get(log.getShopId());
//            if (CollectionUtils.isEmpty(auditLogs)){
//                auditLogs = new ArrayList<>();
//            }
//            auditLogs.add(log);
//            logMap.put(log.getShopId(),auditLogs);
//        }


        return shopPageList;
    }
}
